package com.xtianzhuang.www.tag;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xtianzhuang.www.dao.TdSStaticMapper;
import com.xtianzhuang.www.entity.TdSStatic;
import com.xtianzhuang.www.entity.TdSStaticExample;
import com.xtianzhuang.www.utils.Common;
import com.xtianzhuang.www.utils.SingletonFactory;
import com.xtianzhuang.www.utils.SpringContextHolder;

public class OptionsTag extends SimpleTagSupport {
	private static final Common common = SingletonFactory.getInstance(Common.class);
	protected final Logger log = LoggerFactory.getLogger(this.getClass());
	/**
	 * 用于根据typeId查询 tdSStatic
	 */
	private String typeId;
	/**
	 * 默认值
	 */
	private String defaultValue;
	/**
	 * 是否全部显示
	 */
	private boolean isfull;
	/**
	 * 全部的其他显示
	 */
	private String fullName;
	/**
	 * 调用的方法 一般为service.method
	 */
	private String method;
	/**
	 * option 值 一般和method一起用
	 */
	private String value;
	/**
	 * option 文本 一般和method一起用
	 */
	private String text;

	@Override
	public void doTag() throws JspException, IOException {
		// TODO Auto-generated method stub
		super.doTag();
		this.options();
	}

	public void options() throws IOException {
		JspWriter out = super.getJspContext().getOut();
		out.print(this.generateOptions());
	}
	//
	public String generateOptions() {
		StringBuilder options = new StringBuilder();
		if (isfull) {
			if (this.fullName != null) {
				options.append("<option value=\"\">" + this.fullName + "</option>");
			} else {
				options.append("<option value=\"\">全部</option>");
			}
		}

		if (this.method != null) {
			options.append(this.optionsMethod(this.method, this.value, this.text, this.defaultValue));
		} else {
			options.append(this.optionsStatic(this.typeId, this.defaultValue));
		}
		return options.toString();
	}

	public String optionsMethod(String method, String value, String text, String defaultValue) {
		return this.optionsList(this.method(method), value, text, defaultValue);
	}

	public String optionsStatic(String typeId, String defaultValue) {
		return this.optionsList(this.staticlist(typeId), "dataId", "dataName", defaultValue);
	}


	public List<TdSStatic> staticlist(String typeId) {
		TdSStaticExample example = new TdSStaticExample();
		example.or().andTypeIdEqualTo(typeId).andIsDeletedEqualTo("0");
		TdSStaticMapper service = (TdSStaticMapper) SpringContextHolder.getBean("tdSStaticMapper");
		List<TdSStatic> list = service.selectByExample(example);
		return list;
	}

	public List<TdSStatic> method(String method) {
		// 服务名+方法名
		String serviceMethodName = method.substring(0, method.indexOf("("));
		// 服务名
		String serviceName = serviceMethodName.substring(0, serviceMethodName.lastIndexOf("."));
		// 方法名
		String methodName = serviceMethodName.substring(serviceMethodName.lastIndexOf(".") + 1,
				serviceMethodName.length());
		// 参数
		String paramsStr = method.substring(method.indexOf("(") + 1, method.indexOf(")"));
		Object[] params = null;
		Class[] types = null;
		if (!"".equals(paramsStr)) {
			String[] paramsArr = paramsStr.split(",");
			params = new Object[paramsArr.length];
			types = new Class[paramsArr.length];

			for (int i = 0; i < paramsArr.length; ++i) {
				params[i] = paramsArr[i].trim();
				types[i] = String.class;
			}
		}

		Object service = SpringContextHolder.getBean(serviceName);
		List list = null;

		try {
			list = (List) this.callBean(service, methodName, params, types);
		} catch (Exception var14) {
		}
		return list;
	}


	public Object callBean(Object instance, String method_name, Object[] params, Class[] types) throws Exception {
		if (params != null && types != null) {
			for (int i = 0; i < types.length; ++i) {
				if (types[i] == null) {
					types[i] = params[i].getClass();
				}
			}
		}

		Method method = instance.getClass().getMethod(method_name, types);
		return method.invoke(instance, params);
	}

	public String optionsList(List list, String valueItem, String textItem, String defaultValue) {
		StringBuilder str = new StringBuilder();
		if (list != null && !list.isEmpty()) {
			for (int i = 0; i < list.size(); ++i) {
				Object opValue = null;
				Object opText = null;
				Object obj = list.get(i);
				if (obj instanceof Map) {
					Map map = (Map) obj;
					opValue = map.get(valueItem);
					opText = map.get(textItem);
				} else {
					try {
						opValue = common.getValueByFieldName(obj, valueItem);
						opText = common.getValueByFieldName(obj, textItem);
					} catch (Exception e) {
						log.error(e.getMessage(), e);
						opValue = null;
						opText = null;
					}
				}

				String value = stringValue(opValue);
				String text = stringValue(opText);
				str.append("<option value=\"").append(value).append('"').append(getIsSelected(defaultValue, value))
						.append('>').append(text).append("</option>");
			}

			return str.toString();
		} else {
			return str.toString();
		}
	}


	private static String getIsSelected(String value, String selectValue) {
		String isSelected = "";
		if (value != null && selectValue.equals(value)) {
			isSelected = " selected=\"selected\"";
		}

		return isSelected;
	}
	public String getTypeId() {
		return typeId;
	}

	public void setTypeId(String typeId) {
		this.typeId = typeId;
	}

	public String getDefaultValue() {
		return defaultValue;
	}

	public void setDefaultValue(String defaultValue) {
		this.defaultValue = defaultValue;
	}

	public boolean isIsfull() {
		return isfull;
	}

	public void setIsfull(boolean isfull) {
		this.isfull = isfull;
	}

	public String getFullName() {
		return fullName;
	}

	public void setFullName(String fullName) {
		this.fullName = fullName;
	}

	public String getMethod() {
		return method;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	private static String stringValue(Object value) {
		return null == value ? "" : value.toString();
	}
}